package cn.daniellee.plugin.el.command;

import cn.daniellee.plugin.el.EnterLimiter;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;

public class LimiterCommand implements CommandExecutor {

	@Override
	public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
		if (strings.length > 0) {
			// 购买时长
			if (strings[0].equalsIgnoreCase("buy") && strings.length > 1 && !EnterLimiter.getInstance().isLimited() && commandSender instanceof Player) {
				Player player = (Player) commandSender;
				String time = strings[1].toLowerCase();
				// 检查时间格式
				if (Pattern.compile("^\\d+[dhms]?$").matcher(time).matches()) {
					int second;
					char unit = time.charAt(time.length() - 1);
					if (Character.isDigit(unit)) {
						second = Integer.parseInt(time);
					} else {
						int number = Integer.parseInt(time.substring(0, time.length() - 1));
						switch (unit) {
							case 'd':
								second = number * 86400;
								break;
							case 'h':
								second = number * 3600;
								break;
							case 'm':
								second = number * 60;
								break;
							default:
								second = number;
						}
					}
					int price = EnterLimiter.getInstance().getConfig().getInt("setting.second-price", 10);
					int amount = price * second;
					// 执行扣款
					RegisteredServiceProvider<Economy> provider = Bukkit.getServicesManager().getRegistration(Economy.class);
					if (provider == null) {
						player.sendMessage((EnterLimiter.getInstance().getPrefix() + EnterLimiter.getInstance().getConfig().getString("message.no-economy", "&eEconomy plugin not detected, please contact server admins.")).replace("&", "§"));
						return true;
					}
					Economy economy = provider.getProvider();
					if (economy.withdrawPlayer(player, amount).transactionSuccess()) {
						// 发送加时信息
						ByteArrayDataOutput out = ByteStreams.newDataOutput();
						out.writeUTF("Forward");
						out.writeUTF("ALL");
						out.writeUTF("EnterLimiter");
						ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
						DataOutputStream msgOut = new DataOutputStream(msgBytes);
						try {
							msgOut.writeUTF(player.getName());
							msgOut.writeInt(second);
						} catch (IOException ignored) {
						}
						out.writeShort(msgBytes.toByteArray().length);
						out.write(msgBytes.toByteArray());
						player.sendPluginMessage(EnterLimiter.getInstance(), "BungeeCord", out.toByteArray());
						player.sendMessage((EnterLimiter.getInstance().getPrefix() + EnterLimiter.getInstance().getConfig().getString("message.buy-success", "&eThe purchase is successful, you can now enter the server.")).replace("&", "§"));
					} else
						player.sendMessage((EnterLimiter.getInstance().getPrefix() + EnterLimiter.getInstance().getConfig().getString("message.no-money", "&eYour balance is insufficient and the purchase time has failed.")).replace("&", "§"));
				} else
					player.sendMessage((EnterLimiter.getInstance().getPrefix() + EnterLimiter.getInstance().getConfig().getString("message.wrong-time", "&eThe time format is wrong, please check and try again.")).replace("&", "§"));
				// 给予时长
			} else if (strings[0].equalsIgnoreCase("give") && strings.length > 2 && commandSender.hasPermission("enterlimiter.command.give")) {
				String time = strings[2].toLowerCase();
				// 检查时间格式
				if (Pattern.compile("^\\d+[dhms]?$").matcher(time).matches()) {
					int second;
					char unit = time.charAt(time.length() - 1);
					if (Character.isDigit(unit)) {
						second = Integer.parseInt(time);
					} else {
						int number = Integer.parseInt(time.substring(0, time.length() - 1));
						switch (unit) {
							case 'd':
								second = number * 86400;
								break;
							case 'h':
								second = number * 3600;
								break;
							case 'm':
								second = number * 60;
								break;
							default:
								second = number;
						}
					}
					if (EnterLimiter.getInstance().isLimited()) {
						Integer available = EnterLimiter.availableSecond.get(strings[1]);
						available = available == null ? second : available + second;
						EnterLimiter.availableSecond.put(strings[1], available);
						EnterLimiter.getInstance().getPlayerData().set(strings[1] + ".available", available);
						EnterLimiter.getInstance().savePlayerData();
						commandSender.sendMessage((EnterLimiter.getInstance().getPrefix() + EnterLimiter.getInstance().getConfig().getString("message.give-success", "&eSuccessfully give the target time to the target player.")).replace("&", "§"));
					} else {
						// 发送加时信息
						ByteArrayDataOutput out = ByteStreams.newDataOutput();
						out.writeUTF("Forward");
						out.writeUTF("ALL");
						out.writeUTF("EnterLimiter");
						ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
						DataOutputStream msgOut = new DataOutputStream(msgBytes);
						try {
							msgOut.writeUTF(strings[1]);
							msgOut.writeInt(second);
						} catch (IOException ignored) { }
						out.writeShort(msgBytes.toByteArray().length);
						out.write(msgBytes.toByteArray());
						List<Player> players = (List<Player>) Bukkit.getOnlinePlayers();
						if (!players.isEmpty()) {
							players.get(0).sendPluginMessage(EnterLimiter.getInstance(), "BungeeCord", out.toByteArray());
							commandSender.sendMessage((EnterLimiter.getInstance().getPrefix() + EnterLimiter.getInstance().getConfig().getString("message.give-success", "&eSuccessfully give the target time to the target player.")).replace("&", "§"));
						} commandSender.sendMessage("[EnterLimiter]No one is currently online, the message cannot be sent.");
					}
				} else commandSender.sendMessage((EnterLimiter.getInstance().getPrefix() + EnterLimiter.getInstance().getConfig().getString("message.wrong-time", "&eThe time format is wrong, please check and try again.")).replace("&", "§"));
			// 重载插件
			} else if (strings[0].equalsIgnoreCase("reload") && commandSender.hasPermission("enterlimiter.command.reload")) {
				EnterLimiter.getInstance().reloadConfig();
				EnterLimiter.getInstance().loadConfig();
				commandSender.sendMessage((EnterLimiter.getInstance().getPrefix() + EnterLimiter.getInstance().getConfig().getString("message.reload-success", "&eReload has been successful.")).replace("&", "§"));
				// 发送帮助
			} else sendHelp(commandSender);
		} else sendHelp(commandSender);
		return true;
	}

	private void sendHelp(CommandSender commandSender) {
		commandSender.sendMessage(("&m&6---&m&a--------&3 : " + EnterLimiter.getInstance().getConfig().getString("prompt-prefix", "&6EnterLimiter") + "&3 : &m&a--------&m&6---").replace("&", "§"));

		if (!EnterLimiter.getInstance().isLimited()) {
			String buyText =  EnterLimiter.getInstance().getConfig().getString("help.buy", "&eThe length of the game purchased, unit: d|h|m|s.").replace("&", "§");
			TextComponent buyHelp = new TextComponent("/el buy <time>  " + buyText);
			buyHelp.setColor(ChatColor.GRAY);
			buyHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/el buy "));
			buyHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(buyHelp).color(ChatColor.BLUE).create()));
			commandSender.spigot().sendMessage(buyHelp);
		}

		String giveText =  EnterLimiter.getInstance().getConfig().getString("help.give", "&eGive the game duration, unit: d|h|m|s.").replace("&", "§");
		TextComponent giveHelp = new TextComponent("/el give <name> <time>  " + giveText);
		giveHelp.setColor(ChatColor.GRAY);
		giveHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/el give "));
		giveHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(giveHelp).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(giveHelp);

		String reloadText = EnterLimiter.getInstance().getConfig().getString("help.reload", "&eReload configuration.").replace("&", "§");
		TextComponent reloadHelp = new TextComponent("/el reload  " + reloadText);
		reloadHelp.setColor(ChatColor.GRAY);
		reloadHelp.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/el reload"));
		reloadHelp.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(reloadText).color(ChatColor.BLUE).create()));
		commandSender.spigot().sendMessage(reloadHelp);
	}

}
